from DcmConfig.DidInput import DcmDidCfg


def genDcmDidCodeFile(file:str):
    file_write = open(file,'w')
    code = '#include "string.h"\n'
    code += '#include "std_Types.h"\n'
    code += '#include "NvM.h"\n'
    code += '#include "NvM_SWC_WriteBlock.h"\n'
    code += '#include "NvM_SWC_Did.h"\n'

    code += '''
Std_ReturnType Dcm_WriteBlock(NvM_BlockIdType BlockId,uint8 *ErrorCode)
{
    Std_ReturnType Ret;
    uint8 NvM_Manager_Sts = NvM_Get_DID_Write_Sts(BlockId);

    if(Store_Idle == NvM_Manager_Sts)
    {
        NvM_Req_Write(BlockId);
        Ret = DCM_E_PENDING;
    }
    else if((Store_Pending == NvM_Manager_Sts) || (Store_Request == NvM_Manager_Sts))
    {
        /* return 0x78 when NvM_Write_Block_MainFunction invoke in NVM_SWC task */
        Ret = DCM_E_PENDING;
    }
    else if(Store_OK == NvM_Manager_Sts)
    {
        Ret = E_OK;
    }
    else/* if(Store_Error == NvM_Manager_Sts)*/
    {
        *ErrorCode = DCM_E_GENERALPROGRAMMINGFAILURE;
        Ret = E_NOT_OK;
    }


    return Ret;
}

'''
    file_write.write(code)

def genDcmDidCode(DidInfo:DcmDidCfg,file:str):
    file_write = open(file,'a')
    
    if DidInfo.didReadEn == True:
        pass
    if DidInfo.didWriteEn == True :
        code = 'uint8 NvM_DID_' + DidInfo.didNum + '[NVM_CFG_NV_BLOCK_LENGTH_NvMBlockDescriptor_' + DidInfo.didNum + '];\n'
        # code = 'FUNC(Std_ReturnType,DCM_APPL_CODE) DcmDspDataReadFnc_0x' + DidInfo.didNum + ' (P2VAR(uint8,AUTOMATIC,DCM_INTERN_DATA) Data)\n'
        # code += '{\n'
        # code += '   memcpy(Data,NvM_DID_' + DidInfo.didNum + ',NVM_CFG_NV_BLOCK_LENGTH_NvMBlockDescriptor_' + DidInfo.didNum + ');\n'
        # code += '   return E_OK;\n'
        # code += '}\n'
        code = 'FUNC(Std_ReturnType,DCM_APPL_CODE) DcmDspDataWriteFnc_0x' + DidInfo.didNum + ' (P2CONST(uint8,AUTOMATIC,DCM_INTERN_DATA) Data,P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_INTERN_DATA) ErrorCode)\n'
        code += '{\n'
        code += '   Std_ReturnType Ret;\n'
        code += '   (void)ErrorCode;\n'
        code += '   memcpy(NvM_DID_' + DidInfo.didNum + ',Data,NVM_CFG_NV_BLOCK_LENGTH_NvMBlockDescriptor_' + DidInfo.didNum + ');\n'
        code += '   Ret = Dcm_WriteBlock(NvMConf_NvMBlockDescriptor_NvMBlockDescriptor_' + DidInfo.didNum + ',ErrorCode);\n'
        code += '   return Ret;\n'
        code += '}\n'
        code += '\n'
        file_write.write(code)
    if DidInfo.didReadEn == True:
        code = ''
        if DidInfo.storeLoc == 'FLASH':

            code = 'FUNC(Std_ReturnType,DCM_APPL_CODE) DcmDspDataReadFnc_0x' + DidInfo.didNum + ' (P2VAR(uint8,AUTOMATIC,DCM_INTERN_DATA) Data)\n'
            code += '{\n'
            code += '   memcpy(Data,Flash_Did_data.Flash_DID_' + DidInfo.didNum + ',Flash_DID_' + DidInfo.didNum + '_Size);\n'
            code += '   return E_OK;\n'
            code += '}\n'
            code += '\n'
        elif DidInfo.storeLoc == 'RAM':
            code = 'FUNC(Std_ReturnType,DCM_APPL_CODE) DcmDspDataReadFnc_0x' + DidInfo.didNum + ' (P2VAR(uint8,AUTOMATIC,DCM_INTERN_DATA) Data)\n'
            code += '{\n'
            code += '   memcpy(Data,Ram_DID_' + DidInfo.didNum + ',Ram_DID_' + DidInfo.didNum + '_Size);\n'
            code += '   return E_OK;\n'
            code += '}\n'
            code += '\n'
        elif DidInfo.storeLoc == 'EEPROM':
            code = 'FUNC(Std_ReturnType,DCM_APPL_CODE) DcmDspDataReadFnc_0x' + DidInfo.didNum + ' (P2VAR(uint8,AUTOMATIC,DCM_INTERN_DATA) Data)\n'
            code += '{\n'
            code += '   memcpy(Data,NvM_DID_' + DidInfo.didNum + ',NVM_CFG_NV_BLOCK_LENGTH_NvMBlockDescriptor_' + DidInfo.didNum + ');\n'
            code += '   return E_OK;\n'
            code += '}\n'
        file_write.write(code)
        pass

def genNvMDidCode(DidInfo_list:list,file:str):
    c_file_write = open(file+'.c','w')
    h_file_write = open(file+'.h','w')
    c_code = '#include "NvM_SWC_Did.h"\n\n'

    h_code = """
#ifndef NVM_SWC_DID_H 
#define NVM_SWC_DID_H 

#include "Platform_Types.h"
#include "NvM.h"

"""

    flash_en = False
    last_Flash_did = None
    for DidInfo in DidInfo_list:
        if DidInfo.storeLoc == 'FLASH':
            if flash_en == False:
                c_flash_code = '/*FLASH*/\n'
                c_flash_code += '#pragma section farrom "app_version_blk"\n'
                c_flash_code += 'Flash_Did_data_t Flash_Did_data = \n'
                c_flash_code += '{\n'

                h_flash_code = '/*FLASH*/\n'
                # h_struct_flash_code = '#pragma pack 1\n'
                h_struct_flash_code = 'typedef struct \n'
                h_struct_flash_code += '{\n'

            flash_en = True
            
            c_flash_code += '   {'
            for i in range(DidInfo.didLen):
                c_flash_code += '0x00,'
            c_flash_code += '},' + '/*' + DidInfo.didNum + ':' + DidInfo.didDescr + '*/' + '\\\n'

            h_flash_code += '#define Flash_DID_' + DidInfo.didNum + '_Size   ' + str(DidInfo.didLen) + '\n'
            if last_Flash_did == None:
                h_flash_code += '#define Flash_DID_' + DidInfo.didNum + '_ADDR   ' + '0xa027FF80' + '\n\n'
            else:
                h_flash_code += '#define Flash_DID_' + DidInfo.didNum + '_ADDR   ' + \
                                    'Flash_DID_' + last_Flash_did.didNum + '_ADDR' + ' + ' +\
                                    'Flash_DID_' + last_Flash_did.didNum + '_Size' + '\n\n'
            h_struct_flash_code += '    uint8 Flash_DID_' + DidInfo.didNum + '[Flash_DID_' + DidInfo.didNum + '_Size];' + '/*' + DidInfo.didNum + ':' + DidInfo.didDescr + '*/' + '\n'
            last_Flash_did = DidInfo

    if flash_en == True:
        c_flash_code += '};\n'
        c_flash_code += '#pragma section\n\n'
        h_struct_flash_code += '}Flash_Did_data_t;\n'
        h_struct_flash_code += 'extern Flash_Did_data_t Flash_Did_data;\n'
        # h_struct_flash_code += '#pragma pack 0\n\n'

    eeprom_en = False
    for DidInfo in DidInfo_list:
        if DidInfo.storeLoc == 'EEPROM':
            
            if eeprom_en == False:
                c_EEPROM_code = '/*EEPROM*/\n'
                h_EEPROM_code = '\n/*EEPROM*/\n'

            eeprom_en = True
            c_EEPROM_code += 'uint8 NvM_DID_' + DidInfo.didNum + '[NVM_CFG_NV_BLOCK_LENGTH_NvMBlockDescriptor_' + DidInfo.didNum + '];' + '/*' + DidInfo.didNum + ':' + DidInfo.didDescr + '*/' + '\n'
            h_EEPROM_code += 'extern uint8 NvM_DID_' + DidInfo.didNum + '[NVM_CFG_NV_BLOCK_LENGTH_NvMBlockDescriptor_' + DidInfo.didNum + '];' + '/*' + DidInfo.didNum + ':' + DidInfo.didDescr + '*/' + '\n'
    c_EEPROM_code += '\n'
    h_EEPROM_code += '\n'

    ram_en = False
    for DidInfo in DidInfo_list:
        if DidInfo.storeLoc == 'RAM':
            
            if ram_en == False:
                c_ram_code = '/*RAM*/\n'
                h_ram_code = '\n/*RAM*/\n'
                h_ramData_code = ''
            ram_en = True
            c_ram_code += 'uint8 Ram_DID_' + DidInfo.didNum + '[Ram_DID_' + DidInfo.didNum + '_Size];' + '/*' + DidInfo.didNum + ':' + DidInfo.didDescr + '*/' + '\n'
            h_ram_code += '#define Ram_DID_' + DidInfo.didNum + '_Size ' + str(DidInfo.didLen) + '\n'
            h_ramData_code += 'extern uint8 Ram_DID_' + DidInfo.didNum + '[Ram_DID_' + DidInfo.didNum + '_Size];' + '/*' + DidInfo.didNum + ':' + DidInfo.didDescr + '*/' + '\n'
    c_ram_code += '\n'
    h_ramData_code += '\n'

    h_code_hail = '#endif	/* NVM_SWC_DID_H */'

    c_file_write.write(c_code + c_flash_code + c_EEPROM_code + c_ram_code)
    h_file_write.write(h_code + h_flash_code + h_struct_flash_code + h_EEPROM_code +  h_ram_code + h_ramData_code + h_code_hail)